package com.xr.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.xr.constant.MessageConstant;
import com.xr.constant.RedisConstant;
import com.xr.exception.CustomException;
import com.xr.mapper.CheckGroupMapper;
import com.xr.mapper.CheckItemMapper;
import com.xr.mapper.SetMealMapper;
import com.xr.pojo.CheckGroup;
import com.xr.pojo.CheckItem;
import com.xr.pojo.SetMeal;
import com.xr.pojo.SetMealExample;
import com.xr.query.QueryPageBean;
import com.xr.result.PageResult;
import com.xr.service.SetMealService;
import com.xr.utils.QiNiuUtils;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfig;
import redis.clients.jedis.JedisPool;

import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/*
套餐的实现类
* */

@Service(interfaceClass = SetMealService.class)
public class SetMealServiceImpl implements SetMealService {

    //本地注入
    @Autowired
    private SetMealMapper setMealMapper;

    //    本地注入 jedisPool
    @Autowired
    private JedisPool jedisPool;

    //本地注入FreeMarkerConfig
    @Autowired
    private FreeMarkerConfig freeMarkerConfig;

    @Value("${out_put_path}")
    private String out_put_path;//引入FreeMarker配置类中的输出路径

    //    生成当前方法所需要的静态页面
    public void generateMobileStaticHtml() {
//        在生成静态页面之前需要查询数据
        List<SetMeal> setMealList = setMealMapper.selectByExample(null);
        //需要生成套餐列表静态页面
        generateSetMealListHtml(setMealList);
        //需要生成套餐详情静态页面
        generateSetMealDetailsHtml(setMealList);
    }

    //生成套餐列表静态页面
    public void generateSetMealListHtml(List<SetMeal> setMealList) {
        System.out.println("join 套餐列表静态");
        Map map = new HashMap();
//      为模板提供数据 用于生成静态页面
        map.put("setMealList", setMealList);
        for (SetMeal setMeal : setMealList) {
            setMeal.setImg(QiNiuUtils.DOMAIN + setMeal.getImg());
        }
        generateHtml("setmeal.ftl", out_put_path + "mobile_setmeal.html", map);

    }

    //    生成套餐详情静态页面
    public void generateSetMealDetailsHtml(List<SetMeal> setMealList) {
        System.out.println("join 套餐详情静态");
        for (SetMeal setmeal : setMealList) {
            Map map = new HashMap();
            map.put("setmeal", setmeal);
            map.put("setmeal", setMealMapper.queryGroupAndItemInfoBySetMealId(setmeal.getId()));
            setmeal.setImg(QiNiuUtils.DOMAIN+setmeal.getImg());
            generateHtml("setmeal_detail.ftl", out_put_path + "mobile_setmeal_detail_" + setmeal.getId() + ".html", map);
        }
    }

    //  用于生成静态页面 (模板名称、文件名、模板数据)
    private void generateHtml(String templateName, String outputPath, Map<String, Object> map) {
        //1.创建配置类
        Configuration configuration = freeMarkerConfig.getConfiguration();
        //2.加载模板
        Template template = null;
        BufferedWriter bw = null;
        try {
            template = configuration.getTemplate(templateName);
            //3.创建数据模型
            //4.创输出文件路径对象
            bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outputPath), "utf-8"));
            //5.将数据填充到模板
            template.process(map, bw);
            //6.刷新缓冲流
            bw.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (TemplateException e) {
            e.printStackTrace();
        } finally {
            //7.关闭Writer对象
            try {
                bw.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    //查询所有套餐
    @Override
    public List<SetMeal> queryAll() {
        return setMealMapper.selectByExample(null);
    }

    //    根据ID查询套餐
    @Override
    public SetMeal queryById(Integer id) {
        return setMealMapper.selectByPrimaryKey(id);
    }

    //    根据套餐的Id查询检查组和检查项
    @Override
    public SetMeal queryGroupAndItemBySetMealId(Integer id) {
        return setMealMapper.queryGroupAndItemInfoBySetMealId2(id);
    }

    //根据套餐id遍历检查组info之后根据检查组id遍历检查项
    @Override
    public SetMeal queryGroupAndItemBySetMealId2(Integer id) {
        // 查询套餐信息
        SetMeal setmeal = setMealMapper.findById(id);
        // 查询套餐下的检查组
        List<CheckGroup> checkGroups = setMealMapper.findCheckGroupListBySetmealId(id);
        if (null != checkGroups) {
            for (CheckGroup checkGroup : checkGroups) {
                // 通过检查组id检查检查项列表
                List<CheckItem> checkItems = setMealMapper.findCheckItemByCheckGroupId(checkGroup.getId());
                // 设置这个检查组下所拥有的检查项
                checkGroup.setCheckItems(checkItems);
            }
            //设置套餐下的所拥有的检查组
            setmeal.setCheckGroups(checkGroups);
        }
        return setmeal;

    }

    //    分页+条件查询
    @Override
    public PageResult findPage(QueryPageBean queryPageBean) {
        PageHelper.startPage(queryPageBean.getCurrentPage(), queryPageBean.getPageSize(), true);
        if (!StringUtils.isEmpty(queryPageBean.getQueryString())) {
            queryPageBean.setQueryString("%" + queryPageBean.getQueryString() + "%");
        }
        Page<SetMeal> setMeals = setMealMapper.selectByQueryString(queryPageBean.getQueryString());
        return new PageResult(setMeals.getTotal(), setMeals.getResult());
    }

    //    添加
    @Override
    public void add(SetMeal setMeal, Integer[] checkGroup) {
        //新增套餐
        setMealMapper.add(setMeal);
        //设置套餐和檢查組多对多
        Integer id = setMeal.getId();
        this.setSetMealAndCheckGroup(id, checkGroup);
        System.out.println("setmealId:" + id);
        System.out.println("checkgroupid:" + checkGroup);
        //将图片名称保存到redis集合中
        String fileName = setMeal.getImg();
        if (fileName != null) {
            jedisPool.getResource().sadd(RedisConstant.SETMEAL_PIC_DB_RESOURCES, fileName);
        }
//        当添加套餐后需要重新生成静态页面(套餐、列表、详情页面)
        generateMobileStaticHtml();
    }

    //根据套餐id找出检查组id
    @Override
    public List<Integer> selectGroupIdByMealId(Integer MealId) {
        return setMealMapper.selectGroupIdByMealId(MealId);
    }


    //修改
    @Override
    public void update(SetMeal setMeal, Integer[] checkgroupIds) {
//        1、修改基础数据
        setMealMapper.updateByPrimaryKeySelective(setMeal);
//        2、删除关联的检查组
        setMealMapper.deleteRelation(setMeal.getId());
        System.out.println("checkgroupidS:" + checkgroupIds);
//        3、获取选中的检查组在添加进去
        Integer setmealId = setMeal.getId();
        this.setSetMealAndCheckGroup(setmealId, checkgroupIds);
    }

    //删除套餐
    @Transactional
    @Override
    public void delete(Integer id) throws CustomException {
        //检查该套餐是否有订单使用
        Integer count = setMealMapper.isUseInSetMealOrder(id);
        //有订单使用
        if (count > 0) {
            throw new CustomException(MessageConstant.SETMEAL_IN_USE);
        }
        //没有则删除
        setMealMapper.deleteByPrimaryKey(id);
    }

    @Override
    public List<Map<String, Object>> findSetmealCount() {
        return setMealMapper.findSetmealCount();
    }

    //建立套餐和检查组的关系
    public void setSetMealAndCheckGroup(Integer setmealId, Integer[] checkGroupIds) {
        if (checkGroupIds != null && checkGroupIds.length > 0) {
            for (Integer checkgroupId : checkGroupIds) {
                Map<String, Integer> map = new HashMap<>();
                map.put("setmealId", setmealId);
                map.put("checkgroupId", checkgroupId);
                setMealMapper.setSetMealAndCheckGroup(map);
            }
        }

    }

}
